package com.wordplat.quickstart.xutils.image;

import com.wordplat.quickstart.xutils.common.util.LogUtil;
import com.wordplat.quickstart.xutils.http.RequestParams;
import com.wordplat.quickstart.xutils.x;

import ohos.agp.animation.Animator;
import ohos.agp.components.Image;
import ohos.agp.window.service.DisplayManager;
import ohos.media.image.PixelMap;

/**
 * Created by wyouflf on 15/8/21.
 * 图片加载参数
 *
 * @since 2021-05-09
 */
public class ImageOptions {
    public static final ImageOptions DEFAULT = new ImageOptions();

    // region ###################### decode options (equals & hashcode prop) ################
    private int maxWidth = 0;
    private int maxHeight = 0;
    /**
     * // 小于0时不采样压缩. 等于0时自动识别ImageView的宽高和maxWidth.
     */
    private int width = 0;
    /**
     * // 小于0时不采样压缩. 等于0时自动识别ImageView的宽高和maxHeight.
     */
    private int height = 0;
    private boolean crop = false; // crop to (width, height)

    private int radius = 0;
    private boolean square = false;
    private boolean circular = false;
    private boolean autoRotate = false;
    private boolean compress = true;

    private boolean ignoreGif = true;
    private int gifRate = 100;

    private int loadingDrawableId = 0;
    private int failureDrawableId = 0;
    private PixelMap loadingDrawable = null;
    private PixelMap failureDrawable = null;
    private boolean forceLoadingDrawable = true;

    private Image.ScaleMode placeholderScaleType = Image.ScaleMode.INSIDE;
    private Image.ScaleMode imageScaleType = Image.ScaleMode.CENTER;

    private boolean fadeIn = false;
    private Animator animation = null;

    private boolean useMemCache = true;
    private ParamsBuilder paramsBuilder;

    /**
     * ImageOptions
     */
    protected ImageOptions() {
    }

    final void optimizeMaxSize(Image view) {
        if (width > 0 && height > 0) {
            maxWidth = width;
            maxHeight = height;
            return;
        }

        int screenWidth = DisplayManager.getInstance().getDefaultDisplay(x.app()).get().getAttributes().width;
        int screenHeight = DisplayManager.getInstance().getDefaultDisplay(x.app()).get().getAttributes().height;

        if (this == DEFAULT) {
            maxWidth = width = screenWidth * 3 / 2;
            maxHeight = height = screenHeight * 3 / 2;
            return;
        }

        if (width < 0) {
            maxWidth = screenWidth * 3 / 2;
            compress = false;
        }
        if (height < 0) {
            maxHeight = screenHeight * 3 / 2;
            compress = false;
        }

        if (view == null && maxWidth <= 0 && maxHeight <= 0) {
            maxWidth = screenWidth;
            maxHeight = screenHeight;
        } else {
            int tempWidth = maxWidth;
            int tempHeight = maxHeight;

            if (tempWidth <= 0) {
                tempWidth = screenWidth;
            }
            if (tempHeight <= 0) {
                tempHeight = screenHeight;
            }

            maxWidth = tempWidth;
            maxHeight = tempHeight;
        }
    }

    public int getMaxWidth() {
        return maxWidth;
    }

    public int getMaxHeight() {
        return maxHeight;
    }

    public int getWidth() {
        return width;
    }

    public int getHeight() {
        return height;
    }

    public boolean isCrop() {
        return crop;
    }

    public int getRadius() {
        return radius;
    }

    public boolean isSquare() {
        return square;
    }

    public boolean isCircular() {
        return circular;
    }

    public boolean isIgnoreGif() {
        return ignoreGif;
    }

    public int getGifRate() {
        return gifRate;
    }

    public boolean isAutoRotate() {
        return autoRotate;
    }

    public boolean isCompress() {
        return compress;
    }

    public PixelMap getLoadingDrawable(Image view) {
        if (loadingDrawable == null && loadingDrawableId > 0 && view != null) {
            try {
                view.setImageAndDecodeBounds(loadingDrawableId);
                loadingDrawable = view.getPixelMap();
            } catch (Throwable ex) {
                LogUtil.e(ex.getMessage(), ex);
            }
        }
        return loadingDrawable;
    }

    /**
     * getFailureDrawable
     *
     * @param view
     * @return PixelMap
     */
    public PixelMap getFailureDrawable(Image view) {
        if (failureDrawable == null && failureDrawableId > 0 && view != null) {
            try {
                view.setImageAndDecodeBounds(failureDrawableId);
                failureDrawable = view.getPixelMap();
            } catch (Throwable ex) {
                LogUtil.e(ex.getMessage(), ex);
            }
        }
        return failureDrawable;
    }

    public boolean isFadeIn() {
        return fadeIn;
    }

    public Animator getAnimation() {
        return animation;
    }

    public Image.ScaleMode getPlaceholderScaleType() {
        return placeholderScaleType;
    }

    public Image.ScaleMode getImageScaleType() {
        return imageScaleType;
    }

    public boolean isForceLoadingDrawable() {
        return forceLoadingDrawable;
    }

    public boolean isUseMemCache() {
        return useMemCache;
    }

    public ParamsBuilder getParamsBuilder() {
        return paramsBuilder;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        ImageOptions options = (ImageOptions) o;

        if (maxWidth != options.maxWidth) {
            return false;
        }
        if (maxHeight != options.maxHeight) {
            return false;
        }
        if (width != options.width) {
            return false;
        }
        if (height != options.height) {
            return false;
        }
        if (crop != options.crop) {
            return false;
        }
        if (radius != options.radius) {
            return false;
        }
        if (square != options.square) {
            return false;
        }
        if (circular != options.circular) {
            return false;
        }
        if (autoRotate != options.autoRotate) {
            return false;
        }
        if (compress != options.compress) {
            return false;
        }
        return false;
    }

    @Override
    public int hashCode() {
        int result = maxWidth;
        result = 31 * result + maxHeight;
        result = 31 * result + width;
        result = 31 * result + height;
        result = 31 * result + (crop ? 1 : 0);
        result = 31 * result + radius;
        result = 31 * result + (square ? 1 : 0);
        result = 31 * result + (circular ? 1 : 0);
        result = 31 * result + (autoRotate ? 1 : 0);
        result = 31 * result + (compress ? 1 : 0);
        return result;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder("_");
        sb.append(maxWidth).append("_");
        sb.append(maxHeight).append("_");
        sb.append(width).append("_");
        sb.append(height).append("_");
        sb.append(radius).append("_");
        sb.append(crop ? 1 : 0).append(square ? 1 : 0).append(circular ? 1 : 0);
        sb.append(autoRotate ? 1 : 0).append(compress ? 1 : 0);
        return sb.toString();
    }

    /**
     * ParamsBuilder
     *
     * @since 2021-05-09
     */
    public interface ParamsBuilder {
        /**
         * buildParams
         *
         * @param params
         * @param options
         * @return RequestParams
         */
        RequestParams buildParams(RequestParams params, ImageOptions options);
    }

    public static class Builder {
        protected ImageOptions options;

        /**
         * Builder
         */
        public Builder() {
            newImageOptions();
        }

        /**
         * newImageOptions
         */
        protected void newImageOptions() {
            options = new ImageOptions();
        }

        /**
         * build
         *
         * @return ImageOptions
         */
        public ImageOptions build() {
            return options;
        }

        /**
         * setSize
         *
         * @param width
         * @param height
         * @return Builder
         */
        public Builder setSize(int width, int height) {
            options.width = width;
            options.height = height;
            return this;
        }

        /**
         * setCrop
         *
         * @param crop
         * @return Builder
         */
        public Builder setCrop(boolean crop) {
            options.crop = crop;
            return this;
        }

        /**
         * setRadius
         *
         * @param radius
         * @return Builder
         */
        public Builder setRadius(int radius) {
            options.radius = radius;
            return this;
        }

        /**
         * setSquare
         *
         * @param square
         * @return Builder
         */
        public Builder setSquare(boolean square) {
            options.square = square;
            return this;
        }

        /**
         * setCircular
         *
         * @param circular
         * @return Builder
         */
        public Builder setCircular(boolean circular) {
            options.circular = circular;
            return this;
        }

        /**
         * setAutoRotate
         *
         * @param autoRotate
         * @return Builder
         */
        public Builder setAutoRotate(boolean autoRotate) {
            options.autoRotate = autoRotate;
            return this;
        }


        /**
         * setIgnoreGif
         *
         * @param ignoreGif
         * @return Builder
         */
        public Builder setIgnoreGif(boolean ignoreGif) {
            options.ignoreGif = ignoreGif;
            return this;
        }

        /**
         * setGifRate
         *
         * @param rate
         * @return Builder
         */
        public Builder setGifRate(int rate) {
            options.gifRate = rate;
            return this;
        }

        /**
         * setLoadingDrawableId
         *
         * @param loadingDrawableId
         * @return Builder
         */
        public Builder setLoadingDrawableId(int loadingDrawableId) {
            options.loadingDrawableId = loadingDrawableId;
            return this;
        }

        /**
         * setLoadingDrawable
         *
         * @param loadingDrawable
         * @return Builder
         */
        public Builder setLoadingDrawable(PixelMap loadingDrawable) {
            options.loadingDrawable = loadingDrawable;
            return this;
        }

        /**
         * setFailureDrawableId
         *
         * @param failureDrawableId
         * @return Builder
         */
        public Builder setFailureDrawableId(int failureDrawableId) {
            options.failureDrawableId = failureDrawableId;
            return this;
        }

        /**
         * setFailureDrawable
         *
         * @param failureDrawable
         * @return Builder
         */
        public Builder setFailureDrawable(PixelMap failureDrawable) {
            options.failureDrawable = failureDrawable;
            return this;
        }

        /**
         * setFadeIn
         *
         * @param fadeIn
         * @return Builder
         */
        public Builder setFadeIn(boolean fadeIn) {
            options.fadeIn = fadeIn;
            return this;
        }

        /**
         * setAnimation
         *
         * @param animation
         * @return Builder
         */
        public Builder setAnimation(Animator animation) {
            options.animation = animation;
            return this;
        }

        /**
         * setPlaceholderScaleType
         *
         * @param placeholderScaleType
         * @return Builder
         */
        public Builder setPlaceholderScaleType(Image.ScaleMode placeholderScaleType) {
            options.placeholderScaleType = placeholderScaleType;
            return this;
        }

        /**
         * setImageScaleType
         *
         * @param imageScaleType
         * @return Builder
         */
        public Builder setImageScaleType(Image.ScaleMode imageScaleType) {
            options.imageScaleType = imageScaleType;
            return this;
        }

        /**
         * setForceLoadingDrawable
         *
         * @param forceLoadingDrawable
         * @return Builder
         */
        public Builder setForceLoadingDrawable(boolean forceLoadingDrawable) {
            options.forceLoadingDrawable = forceLoadingDrawable;
            return this;
        }

        /**
         * setUseMemCache
         *
         * @param useMemCache
         * @return Builder
         */
        public Builder setUseMemCache(boolean useMemCache) {
            options.useMemCache = useMemCache;
            return this;
        }

        /**
         * setParamsBuilder
         *
         * @param paramsBuilder
         * @return Builder
         */
        public Builder setParamsBuilder(ParamsBuilder paramsBuilder) {
            options.paramsBuilder = paramsBuilder;
            return this;
        }
    }

}
